import React, { useState } from 'react';
import { Upload, Modal, message } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { UploadChangeParam, UploadFile } from 'antd/lib/upload/interface';
import { reqDeleteImg, AxiosResponse } from '../../../api';
import { BASE_IMG_URL } from '../../../utils/constants';

type Props = {
    uploadedImgsRef: React.MutableRefObject<(() => string[]) | null>;
    imgs: string[] | false;
};

type FileReaderResult = FileReader['result'];

const getBase64 = (file: Blob): Promise<FileReaderResult> => {
    return new Promise((resolve, reject) => {
        const reader: FileReader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
    });
}

const PicturesWall: React.FC<Props> = ({ uploadedImgsRef, imgs }) => {
    const [previewVisible, setPreviewVisible] = useState(false);
    const [previewTitle, setPreviewTitle] = useState<string>('');
    const [previewImage, setPreviewImage] = useState<string>('');
    const [fileList, setFileList] = useState<UploadFile[]>(
        imgs
            ? imgs.map((img, index) => ({
                uid: -index + '',
                name: img,
                status: 'done',
                url: BASE_IMG_URL + img
            }))
            : []
    );
    const handleCancel = (): void => setPreviewVisible(false);
    const handlePreview = async (file: any) => {
        if (!file.url && !file.preview) {
            file.preview = await getBase64(file.originFileObj);
        }
        setPreviewVisible(true);
        setPreviewTitle(file.name || file.url.substring(file.url.lastIndexOf('/') + 1));
        setPreviewImage(file.url || file.preview);
    };
    const handleChange = async ({ file, fileList }: UploadChangeParam): Promise<void> => {
        if (file.status === 'done') {
            const result: any = file.response;
            if (result.status === 0) {
                const { name, url }: any = result.data;
                file.name = name;
                file.url = url;
                message.success('图片上传成功.');
            } else {
                message.error('图片上传失败.');
            }
        } else if (file.status === 'removed') {
            const { data }: AxiosResponse<{
                status: 0 | 1
            }> = await reqDeleteImg(file.name);
            if (data.status === 0) {
                message.success('删除图片成功');
            } else {
                message.error('删除图片失败');
            }
        }
        setFileList([...fileList]);
    };
    const uploadButton: React.ReactNode = (
        <div>
            <PlusOutlined />
            <div style={{ marginTop: 2 }}>上传</div>
        </div>
    );
    const getUploadedImgs = (): string[] => fileList.map(({ name }) => name);
    uploadedImgsRef.current = getUploadedImgs;
    return (
        <div>
            <Upload
                action="/api1/manage/img/upload"
                accept="image/*"
                name="image"
                listType="picture-card"
                fileList={fileList}
                onPreview={handlePreview}
                onChange={handleChange}
            >
                {fileList.length >= 3 ? null : uploadButton}
            </Upload>
            <Modal
                visible={previewVisible}
                title={previewTitle}
                footer={null}
                onCancel={handleCancel}
            >
                <img alt="example" style={{ width: '100%' }} src={previewImage} />
            </Modal>
        </div>
    );
};

export default PicturesWall;